package org.sixtynine.stock.service.file;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.ss.usermodel.WorkbookFactory;
import org.hibernate.criterion.Criterion;
import org.hibernate.criterion.Restrictions;
import org.sixtynine.stock.Constants;
import org.sixtynine.stock.ReturnData;
import org.sixtynine.stock.entity.AnnualShareData;
import org.sixtynine.stock.entity.BaseEntity;
import org.sixtynine.stock.entity.Company;
import org.sixtynine.stock.service.GenericService;
import org.sixtynine.stock.service.business.StockUtil;
import org.sixtynine.stock.util.DateUtil;
import org.sixtynine.stock.util.FileUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

@Component(ExcelProcessorFactory.FILE_TYPE_COMPANY_ANNUAL_SHARE_DATA_LIST)
public class CompanyAnnualDataProcesser extends CompanyDataListProcessor {

	Date formatedDate;

	@Autowired
	GenericService genericService;

	private static Map<Integer, AnnualShareData> exsistingDataMap;

	private static void processExsistingRecords(List<BaseEntity> dataList) {
		exsistingDataMap = new HashMap<Integer, AnnualShareData>();

		for (BaseEntity baseEntity : dataList) {
			AnnualShareData annualShareData = (AnnualShareData) baseEntity;
			exsistingDataMap.put(annualShareData.getYear(), annualShareData);
		}
	}

	public static Map<String, String> methodMap = new HashMap<String, String>();

	@Override
	public ReturnData<List<? extends BaseEntity>> process(String filePath) {

		ReturnData<List<? extends BaseEntity>> returnData = new ReturnData<List<? extends BaseEntity>>(
				Constants.SUCCESS, "");

		init();

		FileInputStream fis = null;

		try {
			List<BaseEntity> annualShareDataList = new ArrayList<BaseEntity>();
			File file = new File(filePath);

			fis = new FileInputStream(file);
			// Get the workbook instance for XLS file
			Workbook workbook = WorkbookFactory.create(fis);

			// Get first sheet from the workbook
			Sheet sheet = workbook.getSheetAt(0);

			Row lastCol = null;
			int lastColNum = 0;
			int lastRow = 0;
			if (sheet.getLastRowNum() > 0) {
				lastRow = sheet.getLastRowNum() + 1;
				lastCol = sheet.getRow(sheet.getLastRowNum());

				lastColNum = lastCol.getLastCellNum();
			}

			double profit, recurringNetProfit, devidends, revenues, ebitda, weightedAverageShareType, devidendOfShare, weightedAverage = 0.00;

			int year = 0;

			String fileName = file.getName();
			String companyCode = fileName.split("_")[0];

			// check file name
			if (!StockUtil.getFileName(fileName).equals(Constants.ANNUAL_DATA)) {
				returnData.setNo(Constants.ERROR);
				returnData.setMsg("Please add quarter data only");
				return returnData;
			}

			Company company = companyMap.get(companyCode);

			if (company == null) {
				returnData.setNo(Constants.ERROR);
				returnData.setMsg("Company code " + companyCode
						+ " not found in the database, wrong file name format");
			}

			Criterion criterion = (Restrictions.eq("company.id",
					company.getId()));

			List<BaseEntity> dataList = genericService.findByCriteria(
					criterion, AnnualShareData.class);

			if (dataList.size() > 0) {
				processExsistingRecords(dataList);
			}

			if (sheet.getLastRowNum() > 0) {
				for (int i = 0; i < lastColNum; i++) {
					if (i != 0) {
						AnnualShareData annualShareData = null;
						// profit = last four quarter recurring profit
						profit = 0.00;
						revenues = 0.00;
						ebitda = 0.00;
						recurringNetProfit = 0.00;
						devidends = 0.00;
						weightedAverageShareType = 0.00;
						devidendOfShare = 0.00;

						for (int a = 0; a < lastRow; a++) {

							Row row = sheet.getRow(a);
							// Get iterator to all cells of current row
							// Iterator<Cell> cellIterator = row.cellIterator();

							Cell cell = row.getCell(i);
							Object cellVal = getCellValue(cell);
							if (i == 0) {
								String cellValText = (String) cellVal;
							}
							switch (a) {

							case 0:
								double yearDbl = (Double) cellVal;
								year = (int) yearDbl;

								if (checkFutureYear(year)) {
									returnData.setNo(Constants.ERROR);
									returnData
											.setMsg("Please enter correct year");
								}
								break;

							case 1:
								revenues = (Double) cellVal;
								break;
							case 2:
								profit = (Double) cellVal;
								break;
							case 3:
								recurringNetProfit = (Double) cellVal;
								break;
							case 4:
								ebitda = (Double) cellVal;
								break;
							case 5:
								weightedAverage = (Double) cellVal;
								break;
							case 6:
								weightedAverageShareType = (Double) cellVal;
								break;
							case 7:
								devidends = (Double) cellVal;
								break;
							case 8:
								devidendOfShare = (Double) cellVal;
								break;
							default:
								break;
							}
						}

						if (company == null) {
							returnData.setNo(Constants.ERROR);
							returnData
									.setMsg("Company Code cannot find for company code "
											+ companyCode);

							return returnData;
						}

						// if (i == 0) {
						// Date date = cell.getDateCellValue();
						if (dataList.size() > 0) {
							if (exsistingDataMap.containsKey(year)) {
								if (exsistingDataMap.get(year).getCompany()
										.getId() == company.getId()) {
									annualShareData = exsistingDataMap
											.get(year);
								} else {
									annualShareData = new AnnualShareData();
								}
							} else {
								annualShareData = new AnnualShareData();
							}

						} else {
							annualShareData = new AnnualShareData();
						}

						// annualShareData = new AnnualShareData();
						annualShareData.setCompany(company);
						annualShareData.setYear(year);
						annualShareData.setNetProfit(profit);
						annualShareData.setRecurringProfit(recurringNetProfit);
						annualShareData.setRevenues(revenues);
						annualShareData.setEbitda(ebitda);
						annualShareData.setDividents(devidends);
						annualShareData.setNumberOfShares(weightedAverage);

						annualShareData.setDividenOfShare(devidendOfShare);
						annualShareData
								.setAveShareOfShare(weightedAverageShareType);
						;

						annualShareDataList.add(annualShareData);

					}
				}
				returnData.setData(annualShareDataList);

			}

		} catch (IOException e) {
			e.printStackTrace();
			returnData.setNo(Constants.ERROR);
			returnData.setMsg(e.getMessage());
		} catch (Exception e) {
			e.printStackTrace();
			returnData.setNo(Constants.ERROR);
			returnData.setMsg(e.getMessage());
		} finally {
			FileUtil.close(fis);
		}

		return returnData;
	}

	public boolean checkFutureYear(int year) {

		int currentYear = DateUtil.getYearFromDate(new Date());

		return currentYear < year;
	}

}
